﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace WebApp.ViewModels
{
    public class JsonDataModel
    {
        public int Id { get; set; }

        public JObject Values { get; set; }

        /// <summary>
        /// 将JSON结果赋值到Model中
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="checkconflict"></param>
        public void SetModelData<T>(T obj, bool checkconflict = false)
        {
            PropertyInfo[] props = typeof(T).GetProperties();

            foreach (PropertyInfo p in props)
            {
                JToken value;
                if (this.Values.TryGetValue(p.Name, out value))
                {
                    string val = value.ToString();

                    if (checkconflict)
                    {
                        ////并发判断
                        //if (p.Name.ToLower() == "Updatetime")
                        //{
                        //    DateTime? Updatetimedb = (DateTime?)p.GetGetMethod().Invoke(obj, new Object[] { });
                        //    DateTime? Updatetime = string.IsNullOrEmpty(val) ? new Nullable<DateTime>() : Convert.ToDateTime(val);
                        //    if (!Updatetimedb.Equals(Updatetime))
                        //    {
                        //        throw new Exception("保存失败！在您提交前数据已经被修改，请刷新后重试！");
                        //    }
                        //}
                    }

                    if (p.PropertyType == typeof(int))
                    {
                        p.GetSetMethod().Invoke(obj, new object[] { string.IsNullOrEmpty(val) ? 0 : Convert.ToInt32(val) });
                    }
                    else if (p.PropertyType == typeof(int?))
                    {
                        p.GetSetMethod().Invoke(obj, new object[] { string.IsNullOrEmpty(val) ? new Nullable<int>() : Convert.ToInt32(val) });
                    }
                    else if (p.PropertyType == typeof(Int16))
                    {
                        p.GetSetMethod().Invoke(obj, new object[] { string.IsNullOrEmpty(val) ? new Nullable<Int16>() : Convert.ToInt16(val) });
                    }
                    else if (p.PropertyType == typeof(Int16?))
                    {
                        p.GetSetMethod().Invoke(obj, new object[] { string.IsNullOrEmpty(val) ? new Nullable<Int16>() : Convert.ToInt16(val) });
                    }
                    else if (p.PropertyType == typeof(decimal))
                    {
                        p.GetSetMethod().Invoke(obj, new object[] { string.IsNullOrEmpty(val) ? 0 : Convert.ToDecimal(val) });
                    }
                    else if (p.PropertyType == typeof(decimal?))
                    {
                        p.GetSetMethod().Invoke(obj, new object[] { string.IsNullOrEmpty(val) ? new Nullable<decimal>() : Convert.ToDecimal(val) });
                    }
                    else if (p.PropertyType == typeof(DateTime))
                    {
                        p.GetSetMethod().Invoke(obj, new object[] { Convert.ToDateTime(val) });
                    }
                    else  if (p.PropertyType == typeof(DateTime?))
                    {
                        p.GetSetMethod().Invoke(obj, new object[] { string.IsNullOrEmpty(val) ? new Nullable<DateTime>() : Convert.ToDateTime(val) });
                    }
                    else if (p.PropertyType == typeof(Boolean))
                    {
                        p.GetSetMethod().Invoke(obj, new object[] { string.IsNullOrEmpty(val) ? new Nullable<Boolean>() : Convert.ToBoolean(val) });
                    }
                    else if (p.PropertyType == typeof(Boolean?))
                    {
                        p.GetSetMethod().Invoke(obj, new object[] { string.IsNullOrEmpty(val) ? new Nullable<Boolean>() : Convert.ToBoolean(val) });
                    }
                    else
                    {
                        p.GetSetMethod().Invoke(obj, new object[] { val });
                    }
                }
            }
        }
    }
}
